use aes_gcm::{Aes256Gcm, KeyInit, aead::{Aead, generic_array::GenericArray}};
use anyhow::Context;
use base64::prelude::*;
use rand::RngCore;
use serde::{Serialize, Deserialize};

type Nonce = GenericArray<u8, aes_gcm::aead::generic_array::typenum::U12>;

#[derive(Serialize, Deserialize)]
pub struct EncryptedConfig {
    pub key: String,
    pub nonce: String,
    pub data: String,
}

#[allow(dead_code)]
pub struct ConfigEncrypter {
    cipher: Aes256Gcm,
    nonce: Nonce,
    key_bytes: Vec<u8>,
}

#[allow(dead_code)]
impl ConfigEncrypter {
    pub fn from_random() -> anyhow::Result<Self> {
        let mut key_bytes = [0u8; 32];
        rand::thread_rng().fill_bytes(&mut key_bytes);

        let mut nonce_bytes = [0u8; 12];
        rand::thread_rng().fill_bytes(&mut nonce_bytes);

        Self::from_bytes(&key_bytes, &nonce_bytes)
    }

    pub fn from_bytes(key: &[u8], nonce: &[u8]) -> anyhow::Result<Self> {
        let cipher = Aes256Gcm::new_from_slice(key)
            .map_err(|e| anyhow::anyhow!("密钥长度不正确（应为32字节）: {}", e))?;

        let nonce = Nonce::from_slice(nonce);

        Ok(Self {
            cipher,
            nonce: *nonce,
            key_bytes: key.to_vec(),
        })
    }

    pub fn encrypt(&self, data: &str) -> anyhow::Result<EncryptedConfig> {
        let encrypted = self.cipher
            .encrypt(&self.nonce, data.as_ref())
            .map_err(|e| anyhow::anyhow!("数据加密失败: {}", e))?;

        Ok(EncryptedConfig {
            key: BASE64_STANDARD.encode(&self.key_bytes),
            nonce: BASE64_STANDARD.encode(self.nonce.as_slice()),
            data: BASE64_STANDARD.encode(&encrypted),
        })
    }

    pub fn decrypt(config: &EncryptedConfig) -> anyhow::Result<String> {
        let key_bytes = BASE64_STANDARD.decode(&config.key)
            .context("base64解码失败（密钥）")?;

        let nonce_bytes = BASE64_STANDARD.decode(&config.nonce)
            .context("base64解码失败（nonce）")?;

        if nonce_bytes.len() != 12 {
            return Err(anyhow::anyhow!("nonce长度不正确（应为12字节）"));
        }

        let ciphertext = BASE64_STANDARD.decode(&config.data)
            .context("base64解码失败（密文）")?;

        let cipher = Aes256Gcm::new_from_slice(&key_bytes)
            .map_err(|e| anyhow::anyhow!("密钥长度不正确（应为32字节）: {}", e))?;

        let nonce = Nonce::from_slice(&nonce_bytes);

        let decrypted = cipher
            .decrypt(nonce, ciphertext.as_ref())
            .map_err(|e| anyhow::anyhow!("数据解密失败: {}", e))?;

        String::from_utf8(decrypted).context("UTF-8解码失败")
    }
}